
// experimental testing is writen according to the requirement, you would better write your own style.
package pointtest;

import java.awt.*;
import java.awt.font.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.Event;
import java.util.Date;
import java.util.ArrayList;
import java.io.*;

/**
 *
 * @author Administrator
 *
 */class Experiment extends JPanel
{
    Experiment(TPofDegreeofImportance s,int r)
    {
       prices = s.prices;
       pCount = s.priceCount;
       Xp = new int[pCount];

       TP1= s.PointLevel1;
  
       s.All();
       Huffman1 = s.HuffmanTree1;
       Huffman2 = s.HuffmanTree2;
       Huffman3 = s.HuffmanTree3;
       Huffman4 = s.HuffmanTree4;
       Huffman5 = s.HuffmanTree5;
       Huffman6 = s.HuffmanTree6;
       PIPs = s.PIP;
       PLAs = s.PLA;
       ITPs = s.ITPs;

       C = s.C;
       R = s.R;
       //firt part: uncomment this part for testing the shared no. of points
       /*  int c1 =0, c2 =0, c3 =0, c4 =0;
            if(Huffman6.length>1200)
            {
                c1 =1282; c2 =609; c3 =308; c4 =164;
            }
            else
            {
                c1 =919; c2 =440; c3 =217; c4 =112;
             }
            X1 = new int [c1+2]; X2 = new int [c2+2];X3 = new int [c3+2];X4 = new int [c4+2];
             SortingC(Huffman3,X1,Y1,c1);
             SortingC(Huffman3,X2,Y2,c2);
             SortingC(Huffman3,X3,Y3,c3);
             SortingC(Huffman3,X4,Y4,c4);
             CaculateBE(X1,Y1,c1,6);CaculateBE(X2,Y2,c2,6);CaculateBE(X3,Y3,c3,6);CaculateBE(X4,Y4,c4,6);*/

     }

   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      double leftX = 0;
      double topY = 0;
      double width = 1800;
      double height = 1000;
      int Xlength =4+ 1400/pCount;

      Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
      g2.setPaint(Color.WHITE);
      g2.fill(rect);

          int C =127;


             int v = 2;
             Xhuff3 = new int[C+2+v];
             Xhuff5 = new int[C+2];
             Xhuff6 = new int[C+2+v];

             Xip = new int[C+2];
             Xpip = new int[C+2];
             Xpla = new int [C+2];

            int c1 =0, c2 =0, c3 =0, c4 =0;
            if(Huffman3.length>1200)
            {
                c1 =1282; c2 =609; c3 =308; c4 =164;
            }
            else
            {
                c1 =919; c2 =440; c3 =217; c4 =112;
             }

            X1 = new int [c1+2]; X2 = new int [c2+2];X3 = new int [c3+2];X4 = new int [c4+2];

             SortingC(Huffman3,X1,Y1,c1);SortingC(Huffman3,X2,Y2,c2);SortingC(Huffman3,X3,Y3,c3);SortingC(Huffman3,X4,Y4,c4);
             CaculateBE(X1,Y1,c1,6);CaculateBE(X2,Y2,c2,6);CaculateBE(X3,Y3,c3,6);CaculateBE(X4,Y4,c4,6);

             System.out.print("\n"+AllError(X1)+"!!!!!"+AllError(X2)+"!!!!!"+AllError(X3)+"!!!!!"+AllError(X4)+"!!!!");

             SortingC(Huffman3,Xhuff3,Yhuff3,C+v);
             SortingC(Huffman5,Xhuff5,Yhuff5,C);
             SortingC(Huffman6,Xhuff6,Yhuff6,C+v);

             SortingC(PIPs,Xpip,Ypip,C);
             SortingC(PLAs,Xpla,Ypla,C);

             CaculateBE(Xhuff3,Yhuff3,C+v,3);
             CaculateBE(Xhuff5,Yhuff5,C,5);
             CaculateBE(Xhuff6,Yhuff6,C+v,6);

             CaculateBE(Xip,Yip,C,7);
             CaculateBE(Xpip,Ypip,C,8);
             CaculateBE(Xpla,Ypla,C,9);

        int [] temp = countPeriodTP(X4);
        for (int i =0;i<temp.length;i++)
        {
             System.out.print("\n"+temp[i]+"??!");
        }

        caculateXY();

      BasicStroke   stroke=new   BasicStroke(2);
      g2.setStroke(stroke);

      g2.setColor(Color.BLACK);

      g2.drawPolyline(Xp, Yp, pCount);

      g2.drawPolyline(X1, Y1, X1.length-1);

      g2.drawPolyline(X2, Y2, X2.length-1);

      g2.drawPolyline(X3, Y3, X3.length-1);

      g2.drawPolyline(X4, Y4, X4.length-1);

      int up =-15;
      g2.drawString("No.of TPs= 2590:"+"", Xp[0]-20,Yp[0]+up);
      g2.drawString("No.of TPs= 1284:"+"", X1[0]-20,Y1[0]+up);
      g2.drawString("No.of TPs= 611:"+"", X2[0]-20,Y2[0]+up);
      g2.drawString("No.of TPs= 310:"+"", X3[0]-20,Y3[0]+up);
      g2.drawString("No.of TPs= 166:"+"", X4[0]-20,Y4[0]+up);

  /*    float[]   dash2   =   {6.0f,   4.0f,   2.0f,   4.0f,   2.0f,   4.0f};
      BasicStroke bs   =   new   BasicStroke(2.0f,   BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,   10.0f,   dash2,   0.0f);
      g2.setStroke(bs);
      g2.setColor(Color.BLACK);
      g2.drawPolyline(Xp, Yp3, pCount);
      g2.drawPolyline(Xp, Yp5, pCount);
      g2.drawPolyline(Xp, Yp6, pCount);
      g2.drawPolyline(Xp, Yp8, pCount);
      g2.drawPolyline(Xp, Yp9, pCount);
      int t =50;
      g2.drawString("ITP(Sum-PsD)"+"", Xp[0],Yp3[0]+t);
      g2.drawString("N- Max-PD"+"", Xp[0],Yp5[0]+t);
      g2.drawString("ITP(N-Min-TPD)"+"", Xp[0],Yp6[0]+t);
      g2.drawString("PIPs"+"", Xp[0],Yp8[0]+t);
      g2.drawString("PLAs"+"", Xp[0],Yp9[0]+t);*/

          g2.drawRect(40, 100, 810, 545);  

    //  g2.drawLine(340, 170, 340, 635);g2.drawLine(740, 170, 740, 635);g2.drawLine(940, 170, 940, 635);
       for(int i =0;i<Xp.length+1;)
      {
          g2.drawString(i+" ", Xp[i],660);
          i+=300;
      }

       g2.drawString(Xp.length +" ", Xp[Xp.length-1],660);

       // below is used to test the error and compression, you would better write by yourself.
     // g2.drawRect(55, 5, 1040,655);
/*
      g2.drawRect(55, 10, 1040, 652);
      int[] error1 = new int[TP1.length];
      int[] error2 = new int[TP1.length];
      int[] error3 = new int[TP1.length];
      int[] error5 = new int[TP1.length];
      int[] error6 = new int[TP1.length];
      int[] error7 = new int[TP1.length];
      int[] count1 = new int[TP1.length], count2 = new int[TP1.length], count3 =new int[TP1.length], count6 =new int[TP1.length],count7 =new int[TP1.length];
      for(int C = 0;C<TP1.length;C++)
      {

         //     Xhuff1 = new int[C+2];
              Xhuff2 = new int[C+2];
              Xhuff3 = new int[C+2];
             // Xhuff5 = new int[C+2];
              Xhuff6 = new int[C+2];
              Xhuff1 = new int[C+2];
              Xhuff7 = new int[C+2];


           //  SortingC(IPs,Xhuff1,Yhuff1,C);
             SortingC(PLAs,Xhuff1,Yhuff1,C);
             SortingC(PIPs,Xhuff2,Yhuff2,C);
             SortingC(ITPs,Xhuff7,Yhuff1,C);
             SortingC(Huffman3,Xhuff3,Yhuff3,C);
           //  SortingC(Huffman5,Xhuff5,Yhuff5,C);
             SortingC(Huffman6,Xhuff6,Yhuff6,C);


             CaculateBE(Xhuff1,Yhuff1,C,3);
             CaculateBE(Xhuff7,Yhuff1,C,7);
             if (C == TP1.length-1)
             {
                 for(int i =0;i< Xhuff6.length;i++)
                     System.out.print(Xhuff6[i]+"!");
             }
             CaculateBE(Xhuff2,Yhuff2,C,5);
             CaculateBE(Xhuff3,Yhuff3,C,3);
           //  CaculateBE(Xhuff5,Yhuff5,C,5);
             CaculateBE(Xhuff6,Yhuff6,C,6);


             int r =100;
             error3[C] = (AllError(Xhuff3));
           // error1[C] = 680-AllError(Xhuff1);
             error2[C] = (AllError(Xhuff2));
             error1[C] = (AllError(Xhuff1));
            // error5[C] = 680-AllError(Xhuff5);
             error6[C] = (AllError(Xhuff6));
             error7[C] = (AllError(Xhuff7));

             count1[C] = cout(Xhuff1);
             count2[C] = cout(Xhuff2);
             count3[C] = cout(Xhuff3);
             count6[C] = cout(Xhuff6);
             count7[C] = cout(Xhuff7);

           //  g2.drawString(error1[C]+"!!", 20,20*C);
       }
      
      int T = 12;
      int[] Compresson1 = new int[T];
      int[] Compresson2 = new int[T];
      int[] Compresson3 = new int[T];
     // int[] Compresson5 = new int[T];
      int[] Compresson6 = new int[T];
      int[] Compresson7 = new int[T];

      Compresson1 = caculatX(Compresson1);
      Compresson2 = caculatX(Compresson2);
      Compresson3 = caculatX(Compresson3);
     // Compresson5 = caculatX(Compresson5);
      Compresson6 = caculatX(Compresson6);
      Compresson7 = caculatX(Compresson7);

      int[] Cerror1 = new int[T];
      int[] Cerror2 = new int[T];
      int[] Cerror3 = new int[T];
    //  int[] Cerror5 = new int[T];
      int[] Cerror6 = new int[T];
      int[] Cerror7 = new int[T];

      int[] Ctrends1 = new int[T],Ctrends2 = new int[T],Ctrends3 = new int[T],Ctrends6 = new int[T],Ctrends7 = new int[T];


       for(int i =0;i<Compresson2.length;i++)
      {
          int x = (int) pCount/(i+1);
          if(x>error2.length)
          {
              Cerror1[i] = error2[error2.length-1];
              Cerror2[i] = error2[error2.length-1];
              Cerror3[i] = error3[error2.length-1];
              Cerror6[i] = error6[error2.length-1];
              Cerror7[i] = error6[error2.length-1];

              Ctrends1[i] = count1[count1.length-1];
              Ctrends2[i] = count2[count2.length-1];
              Ctrends3[i] = count3[count3.length-1];
              Ctrends6[i] = count6[count6.length-1];
              Ctrends7[i] = count7[count7.length-1];
          }
        else
          {
              x=x-1;
              Cerror1[i] = error1[x];
              Cerror2[i] = error2[x];
              Cerror3[i] = error3[x];
              Cerror6[i] = error6[x];
              Cerror7[i] = error7[x];
              
               Ctrends1[i] = count1[x];
               Ctrends2[i] = count2[x];
               Ctrends3[i] = count3[x];
               Ctrends6[i] = count6[x];
               Ctrends7[i] = count7[x];
        }
      }

       print("d:\\CPLAs.txt",Cerror1);
       print("d:\\CPIPs.txt",Cerror2);
       print("d:\\CSum-PsD.txt",Cerror3);
       print("d:\\CN-Min-TPD.txt",Cerror6);
       print("d:\\C-ITP.txt",Cerror7);

       print("d:\\TPLAs.txt",Ctrends1);
       print("d:\\TPIPs.txt",Ctrends2);
       print("d:\\TSum-PsD.txt",Ctrends3);
       print("d:\\TN-Min-TPD.txt",Ctrends6);
       print("d:\\T-ITP.txt",Ctrends7);
*/

       // testing the tree
   /*    Mark = new int[R.length][R[0].length];

       TreeIndex = 0;
       Tree = new int[R.length];
       Print(1,R[0].length-1);

        g2.setColor(Color.BLACK);
     
        for (int i = 0;i <R.length;i++)
       {
         // g2.drawLine(0,i*15,100,1000);
          for(int j =0;j<R[i].length;j++)
           {
               if(i==0);
                //g2.drawString(j+ ";", (j)*20,i*15+10);
               else if (Mark[i][j]==1);
              //   g2.drawString(R[i][j]+ ";", (j)*20,i*15+15);

           }
       }

       Tree[TreeIndex] = R[1][R[0].length-1];
       int[] I1 = new int[Tree.length];
       int[] I2 = new int[Tree.length];
       I1[TreeIndex] = 1;
       I2[TreeIndex++] = R[0].length-1;*/

    }

    private int[] countPeriodTP(int[] TP)
    {
        int[] Count = new int[6];
        for(int i =0;i<Count.length;i++)
            Count[i] = 0;
        for(int i =0;i < TP.length;i++)
        {
            if(TP[i]<=490)
                Count[0]++;
            else if(TP[i]<=980)
                 Count[1]++;
            else if(TP[i]<=1470)
                 Count[2]++;
            else if(TP[i]<=1960)
                 Count[3]++;
            else if(TP[i]<=2450)
                 Count[4]++;
            else
                Count[5]++;
        }
         return Count;
    }

   private int cout (int[] p)
    {
       int count =0 ;
       for(int i =1; i<p.length-1;i++)
      {
          if(prices[p[i]].Price<prices[p[i-1]].Price&&prices[p[i]].Price<prices[p[i+1]].Price)
              count++;
          if(prices[p[i]].Price>prices[p[i-1]].Price&&prices[p[i]].Price>prices[p[i+1]].Price)
              count++;
      }
       return count;
   }

   private void print  (String s, int[] error)
    {
      try
      {
       FileWriter fileWriter=new FileWriter(s);
       for (int i = 0; i < error.length; i++) {
        fileWriter.write(String.valueOf(i+1)+" "+String.valueOf(error[i])+"\r\n");
         }
       fileWriter.flush();
       fileWriter.close();
       }catch (Exception e) {
             e.printStackTrace();
       }

              /*
               * try
      {
       FileWriter fileWriter=new FileWriter("c:\\CSum-PsD.txt");
       for (int i = 0; i < Cerror3.length; i++) {
        fileWriter.write(String.valueOf(i+1)+" "+String.valueOf(Cerror3[i])+"\r\n");
         }
       fileWriter.flush();
       fileWriter.close();
       }catch (Exception e) {
             e.printStackTrace();
       }

       try
      {
       FileWriter fileWriter=new FileWriter("c:\\CN-Min-TPD.txt");
       for (int i = 0; i < Cerror6.length; i++) {
        fileWriter.write(String.valueOf(i+1)+" "+String.valueOf(Cerror6[i])+"\r\n");
         }
       fileWriter.flush();
       fileWriter.close();
       }catch (Exception e) {
             e.printStackTrace();
       }
               */
    }
   private int[] caculatX(int[] x)
   {
       int t = pCount/x.length;
       for(int i =0;i<x.length;i++)
       {
           x[i] = t*i+55;
       }
       return x;
   }

   private int AllError(int[] Xhuff)
   {
       double error = 0;
       for(int i = 1;i<Xhuff.length;i++)
       {
           error += CaculateError(Xhuff[i-1],Xhuff[i]);
       }
       return (int)(error/4000);
   }


   private double CaculateError(int i, int j)
   {
        double error = 0;
        for(int k = i;k<j;k++)
           error += Math.abs(prices[i].Price + ( prices[j].Price-prices[i].Price) *((k-i) / (j-i)) - prices[k].Price);
        return error;
   }

    private void Print(int i, int j)
    {
        int x=0 ;
        {
            Mark[i][j] = 1;
            x = R[i][j];
         }
            if(x > i && x!= 0)
                 Print(i,x-1);

            if(x+1 < Mark.length&&x<j&& x!= 0)
                 Print(x+1,j); 
           
    }

    private void caculateXY()
    {
      /* int D=250;
       double Xlength =0.39;//(int) 1400 /pCount;
       double Scale=-0.01;*/
         int D=425;//;490;
       double Xlength =0.3;
       double Scale=-0.01;
       int n = 75,w=-55;

       Yp = new int[pCount];

       Yp3 = new int[pCount];
       Yp5 = new int[pCount];
       Yp6 = new int[pCount];
       Yp7 = new int[pCount];
       Yp8 = new int[pCount];
       Yp9 = new int[pCount];

       Yhuff3 = new int[Xhuff3.length];
       Yhuff5 = new int[Xhuff5.length];
       Yhuff6 = new int[Xhuff6.length];
       Yip = new int[Xip.length];
       Ypip = new int[Xpip.length];
       Ypla = new int[Xpla.length];

       //int n = 75,w=-55;
       for(int i = 0;i<TP1.length;i++)
       {
           TP1[i] = TP1[i]+25;
       }
       for(int i =0;i<pCount;i++)
        {
           Xp[i] =(int)(10+i*Xlength-w);
           Yp[i] = (int) Math.round (Scale* prices[i].Price+D);

           Yp3[i] = Yp[i]+5*n;
           Yp5[i] = Yp[i]+5*n;
           Yp6[i] = Yp[i]+6*n;
           Yp7[i] = Yp[i]+5*n;
           Yp8[i] = Yp[i]+7*n;
           Yp9[i] = Yp[i]+8*n;
        }

           for(int i =0;i<Xhuff3.length;i++)
        {
            Yhuff3[i] = (int)Math.round (Scale*prices[Xhuff3[i]].Price+D+4*n);
            Xhuff3[i] =(int) (10+ Xhuff3[i]*Xlength-w);
        }
           for(int i =0;i<Xhuff5.length;i++)
        {
            Yhuff5[i] = (int)Math.round (Scale*prices[Xhuff5[i]].Price+D+4*n);
            Xhuff5[i] =(int)(10+ Xhuff5[i]*Xlength-w);
        }
           for(int i =0;i<Xhuff6.length;i++)
        {
            Yhuff6[i] = (int)Math.round (Scale*prices[Xhuff6[i]].Price+D+5*n);
            Xhuff6[i] =(int)(10+ Xhuff6[i]*Xlength-w);
        }
          for(int i =0;i<Xip.length;i++)
        {
            Yip[i] = (int)Math.round (Scale*prices[Xip[i]].Price+D+4*n);
            Xip[i] =(int)(10+ Xip[i]*Xlength);
        }
         for(int i =0;i<Xpip.length;i++)
        {
            Ypip[i] = (int)Math.round (Scale*prices[Xpip[i]].Price+D+6*n);
            Xpip[i] =(int) (10+ Xpip[i]*Xlength-w);
        }
           for(int i =0;i<Xpla.length;i++)
        {
            Ypla[i] = (int)Math.round (Scale*prices[Xpla[i]].Price+D+7*n);
            Xpla[i] =(int) (10+ Xpla[i]*Xlength-w);
        }

         Y1 = new int [X1.length];
         for(int i =0;i<X1.length;i++)
        {
            Y1[i] = (int)Math.round (Scale*prices[X1[i]].Price+D+1*n);
            X1[i] =(int) (10+ X1[i]*Xlength-w);
        }
         Y2 = new int [X2.length];
         for(int i =0;i<X2.length;i++)
        {
            Y2[i] = (int)Math.round (Scale*prices[X2[i]].Price+D+2*n);
            X2[i] =(int) (10+ X2[i]*Xlength-w);
        }
         Y3 = new int [X3.length];
         for(int i =0;i<X3.length;i++)
        {
            Y3[i] = (int)Math.round (Scale*prices[X3[i]].Price+D+3*n);
            X3[i] =(int) (10+ X3[i]*Xlength-w);
        }
         Y4 = new int [X4.length];
         for(int i =0;i<X4.length;i++)
        {
            Y4[i] = (int)Math.round (Scale*prices[X4[i]].Price+D+4*n);
            X4[i] =(int) (10+ X4[i]*Xlength-w);
        }

   }
     private void SortingC(int[] Huffman,int [] Xhuff,int[] Yhuff,int C)
   {
      for(int i = C;i > 0;i--)
      {
          int x = Huffman[Huffman.length-i],j=C;
          for(;j>-1&&Xhuff[j]>x;j--)
              ;
          for(int k=2;k<=j;k++)
              Xhuff[k-1]=Xhuff[k];
          Xhuff[j] = x;
      }
   }
  private void CaculateBE(int[] Xhuff,int[] Yhuff,int C,int k)
   {
       {
          Xhuff[0]=0;//Xp[0];
          Xhuff[C+1]=pCount-1;//Xp[Xp.length-1];
        //  Yhuff[0] = Yp[0]+(k-1)*80;
         // Yhuff[C+1] = Yp[Xp.length-1]+(k-1)*80;
      }
    }
  StockPrice[] prices;
  int pCount;
  private int[] TP; private int[]TP1;  
  public int[] Xp, Xhuff1,Xhuff2,Xhuff3,Xhuff4,Xhuff5,Xhuff6,Xhuff7,Xip,Xpip,Xpla,X1,X2,X3,X4;
  private int[] Yp,Yp2,Yp3,Yp4,Yp5,Yp6,Yp7,Yp8,Yp9,Yhuff1,Yhuff2,Yhuff3,Yhuff4,Yhuff5,Yhuff6,Yip,Ypip,Ypla,Y1,Y2,Y3,Y4;
  private int[] Huffman1,Huffman2,Huffman3,Huffman4,Huffman5,Huffman6,PIPs,PLAs,ITPs;
  private int[] Sorting;
  int[][] C,R;
  int[][] Mark;
  int [] Tree;
  int TreeIndex;
 
}